using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;

namespace OracleInternal.BinXml
{
	internal class ObxmlProcessor
	{
		private ObxmlDecodeContext m_DecodeContext;

		private object m_DecodeContextLock = new object();

		internal ObxmlProcessor()
		{
		}

		internal ObxmlDecodeStream GetDecodeStream(OracleConnection conn, OracleBlob csxBlob)
		{
			if (conn == null && csxBlob == null)
			{
				throw new OracleException(ResourceStringConstants.XML_TYPE_BINARY_INTERNAL_ERROR, string.Empty, string.Empty, ObxmlDecodeResponse.GetErrorMessage(ObxmlErrorTypes.InvalidArguments));
			}
			if (conn == null)
			{
				conn = csxBlob.Connection;
			}
			if (m_DecodeContext != null)
			{
				lock (m_DecodeContextLock)
				{
					if (m_DecodeContext != null)
					{
						ObxmlDecodeStream obj = (ObxmlDecodeStream)m_DecodeContext;
						obj.ResetRequestObject(m_DecodeContext, csxBlob).DbConnection = conn;
						m_DecodeContext = null;
						return obj;
					}
				}
			}
			ObxmlTokenManager oracleBinXmlTokenManager = ObxmlTokenManager.GetOracleBinXmlTokenManager(conn);
			ObxmlDecodeContext obxmlDecodeContext = ObxmlDecodeContext.CreateDefaultContext(conn);
			ObxmlMetaDataRepository defaultMetaDataRepository = oracleBinXmlTokenManager.GetDefaultMetaDataRepository(bDisposeMetaDataRepository: true, obxmlDecodeContext);
			ObxmlTokenMap tokenMap = oracleBinXmlTokenManager.Open(obxmlDecodeContext.TokenMapContext);
			ObxmlDecodeContext.UpdateContext(obxmlDecodeContext, defaultMetaDataRepository, tokenMap, CsxDecodeChunkingPolicy.None, -1L);
			return new ObxmlDecodeStream(obxmlDecodeContext, csxBlob);
		}

		internal void DisposeDecodeStream()
		{
			lock (m_DecodeContextLock)
			{
				if (m_DecodeContext != null)
				{
					((ObxmlDecodeStream)m_DecodeContext).ResetDecodeState(disposing: true);
					m_DecodeContext = null;
				}
			}
		}

		internal void CloseDecodeStream(ObxmlDecodeContext decodeContext)
		{
			if (m_DecodeContext == null)
			{
				lock (m_DecodeContextLock)
				{
					if (m_DecodeContext == null)
					{
						m_DecodeContext = decodeContext;
						m_DecodeContext.ResetDecodeState(disposing: false);
						return;
					}
				}
			}
			((ObxmlDecodeStream)decodeContext).ResetDecodeState(disposing: true);
		}
	}
}
